import { rcp } from '@kit.RemoteCommunicationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import {buildURL,buildFullPath} from  "./src/main/js/buildurl"
import { HttpRequestConfig, HttpResponse, HttpUploadResponse, HttpDownloadResponse, RequestTask,
  HttpPromise,
  AnyObject} from './index';



// 定义RequestInterceptor拦截器
export class RequestInterceptor implements rcp.Interceptor {

  public onFulfilled?: (config?: HttpRequestConfig) => HttpRequestConfig;
  public onRejected?: (error: any) => any;

  constructor(onFulfilled?: (config: HttpRequestConfig) => HttpRequestConfig, onRejected?: (error: any) => any) {
    this.onFulfilled = onFulfilled;
    this.onRejected = onRejected;
  }
  // 自定义请求处理逻辑
  async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    try {
      if (this.onFulfilled) {
        let conf:HttpRequestConfig = {
          method:context.request.method,
          header:context.request.headers
        }
        this.onFulfilled(conf);
      }
      //context.request = modifiedConfig; // 使用修改后的请求配置
    } catch (error) {
      if (this.onRejected) {
        return this.onRejected(error); // 如果有拒绝逻辑则调用
      }
    }
    return next.handle(context);
  }
}

// 定义ResponseInterceptor拦截器
export class ResponseInterceptor implements rcp.Interceptor {
  public onFulfilled?: (response?: HttpResponse) => HttpResponse;
  public onRejected?: (error: any) => any;

  constructor(onFulfilled?: (response: HttpResponse) => HttpResponse, onRejected?: (error: any) => any) {
    this.onFulfilled = onFulfilled;
    this.onRejected = onRejected;
  }

  // 自定义响应处理逻辑
  async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    const response = await next.handle(context);
    try {
      if (this.onFulfilled) {
        let resp: HttpResponse = {
          data: response.toJSON(),
          statusCode: response.statusCode,
          errMsg: response.reasonPhrase,
          cookies:response.cookies?.map(cookie => `${cookie.name}=${cookie.value}`),
          header:response.headers
        }
        this.onFulfilled(resp);
      }
    } catch (error) {
      if (this.onRejected) {
        return this.onRejected(error); // 如果有拒绝逻辑则调用
      }
    }
    return response;
  }
}

export abstract class HttpRequestAbstract {
  session:rcp.Session;
  config:HttpRequestConfig;
  requestInterceptor:RequestInterceptor;
  responseInterceptor:ResponseInterceptor;

  constructor(public conf: HttpRequestConfig) {
    this.config = {
      ...conf,
      validateStatus: conf.validateStatus || ((status) => {
        return status >= 200 && status < 300;
      })
    };
    this.requestInterceptor =  new RequestInterceptor();
    this.responseInterceptor =  new ResponseInterceptor();

    const sessionConfig: rcp.SessionConfiguration = {
      baseAddress: conf.baseURL,
      headers: conf.header !== undefined ? conf.header : {'accept': 'application/json'}, // 或者可以用 null 或者其他默认值
      interceptors: [
        this.requestInterceptor,
        this.responseInterceptor
      ],
      requestConfiguration: {
        security: {
          tlsOptions: {
            tlsVersion: 'TlsV1.2'
          }
        }
      }
    }
    this.session = rcp.createSession(sessionConfig);
  }

  // Middleware method
  middleware<T = any>(config: HttpRequestConfig): HttpPromise<T> {
    // 可以在这实现中间件逻辑
    return this.request(config);
  }

  // 主请求方法
  request<T = any>(config: HttpRequestConfig<RequestTask>): HttpPromise<T> {
    return new Promise((resolve, reject) => {
      const fullUrl = buildURL(buildFullPath(this.config.baseURL, config.url), config.params)
      const { method = "GET", url, header, data,params } = config;
      //const fullUrl =`${this.config.baseURL}${url}`;

      const req = new rcp.Request(fullUrl, method, header, data);

      this.session.fetch(req).then((response) => {
        // 解析响应体
        let responseData: T |object| null = null;

        const { validateStatus } = this.config
        if(validateStatus(response.statusCode)){
          try {
            responseData = response.toJSON();
            let resp = {
              config,
              data: responseData as T,
              statusCode: response.statusCode,
              errMsg: response.reasonPhrase,
              cookies:response.cookies?.map(cookie => `${cookie.name}=${cookie.value}`),
              header:response.headers
            };
            resolve(resp)
          } catch (err) {
            console.error('JSON parse error:', err);
            reject(err)
          }
        }else{
          reject(response)
        }
      }
      ).catch((err: BusinessError) => {
        console.log(`err: err code is ${err.code}, err message is ${JSON.stringify(err)}`);
        reject(err)
      });
    });
  }

  // GET 请求
  get<T = any>(url: string, config?: HttpRequestConfig<RequestTask>): HttpPromise<T> {
    return this.request({ ...config, url, method: 'GET' });
  }

  // POST 请求
  post<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<RequestTask>): HttpPromise<T> {
    return this.request({ ...config, url, data, method: 'POST' });
  }

  // PUT 请求
  put<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<RequestTask>): HttpPromise<T> {
    return this.request({ ...config, url, data, method: 'PUT' });
  }

  // DELETE 请求
  delete<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<RequestTask>): HttpPromise<T> {
    return this.request({ ...config, url, data, method: 'DELETE' });
  }

  // 其他 HTTP 请求方法可以类似实现，如 head、options、trace 等
  // 上传
  upload<T = any>(url: string, config?: HttpRequestConfig<RequestTask>): Promise<HttpUploadResponse>{
    return new Promise((resolve, reject) => {
      let fileDir = config.filePath; // 请根据自身业务定义此路径
      let uploadFromFile : rcp.UploadFromFile = {
        fileOrPath : fileDir
      }
      this.session.uploadFromFile(url, uploadFromFile).then((response) => {
        console.info(`Succeeded in getting the response ${response}`);
        let resp = {
          config,
          data: response.toJSON() as T,
          statusCode: response.statusCode,
          errMsg: response.reasonPhrase
        };
        resolve(resp)
      }).catch((err: BusinessError) => {
        console.error(`err: err code is ${err.code}, err message is ${JSON.stringify(err)}`);
        reject(err)
      });
    })
  }
  // 下载
  download(url: string, config?: HttpRequestConfig<RequestTask>): Promise<HttpDownloadResponse>{
    return new Promise((resolve, reject) => {
      let downloadToFile: rcp.DownloadToFile = {
        kind: 'folder',
        path: config.filePath //请根据自身业务选择合适的路径
      } as rcp.DownloadToFile
      this.session.downloadToFile(url, downloadToFile).then((response) => {
        console.info(`Succeeded in getting the response ${response}`);
        let resp = {
          config,
          data: response.toJSON(),
          statusCode: response.statusCode,
          errMsg: response.reasonPhrase,
          tempFilePath:config.filePath,
          header:response.headers,
          cookies:response.cookies?.map(cookie => `${cookie.name}=${cookie.value}`),
        };
        resolve(resp)
      }).catch((err: BusinessError) => {
        console.error(`DownloadToFile failed, the error message is ${JSON.stringify(err)}`);
        reject(err)
      });
    })
  }
}

class HttpRequest extends HttpRequestAbstract {
  setConfig(f) {
    this.config = f(this.config)
  }
}

export default HttpRequest;

